package com.datree.cache_server.controller;

import com.datree.cache_server.common.utils.StringUtils;
import com.datree.cache_server.common.utils.http.HttpUtils;
import com.datree.cache_server.domain.vo.CacheFileParams;
import com.datree.cache_server.framework.config.RuoYiConfig;
import com.datree.cache_server.framework.constant.Constants;
import org.apache.tomcat.jni.FileInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;


@RestController
@RequestMapping("/file")
public class FileCacheController {
    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    private final ExecutorService executorService;

    public FileCacheController(ExecutorService executorService) {
        this.executorService = executorService;
    }

    private String replaceFailName(String str) {
        return StringUtils.replaceEach(str, new String[]{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}, new String[]{"", "", "", "", "", "", "", "", ""});
    }

    private String saveFile(String url, String dirName, String fileName, Boolean waitDownload) throws ExecutionException, InterruptedException {
        Future<?> future = executorService.submit(() -> {
            // 下载图片的逻辑
            // 假设这里有一个下载方法 downloadImageContent(url)
            HttpUtils.sendGetFile(url, dirName, fileName);
        });
        // 调用get()方法会阻塞，直到任务完成
        if (waitDownload) {
            future.get(); // 等待任务完成，不获取结果（因为任务返回void）
        }

        return "";
    }

    @GetMapping("/getFileStreamAutoCache")
    public void getFileStreamAutoCache(@RequestParam("fileUrl") String fileUrl, @RequestParam("groupName") String groupName, @RequestParam("dirName") String dirName, @RequestParam("fileName") String fileName, @RequestParam(name = "waitDownload", required = false, defaultValue = "true") Boolean waitDownload, HttpServletResponse res) throws ExecutionException, InterruptedException, IOException {
        dirName = UriUtils.decode(replaceFailName(dirName), "UTF-8");
        groupName = UriUtils.decode(replaceFailName(groupName), "UTF-8");
        File file = new File(RuoYiConfig.getProfile() + "/" + groupName + "/" + dirName + "/" + fileName);
        if (!file.exists()) {
            log.info("getFileAutoCache - {}/{}/{}", groupName, dirName, fileName);
            saveFile(fileUrl, groupName + "/" + dirName, fileName, waitDownload);
            if(!waitDownload){
                OutputStream outputStream = res.getOutputStream();
                String msg="ok";
                res.addHeader("Content-Length", String.valueOf(msg));
                outputStream.write(msg.getBytes(StandardCharsets.UTF_8));
                outputStream.close();

                return;
            }
            file = new File(RuoYiConfig.getProfile() + "/" + groupName + "/" + dirName + "/" + fileName);
        }

        long length = file.length();
        res.addHeader("Content-Length", String.valueOf(length));
        OutputStream outputStream = res.getOutputStream();
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        FileInputStream inputStream = new FileInputStream(file);
        bis = new BufferedInputStream(inputStream);
        int i = bis.read(buff);
        while (i != -1) {
            outputStream.write(buff, 0, buff.length);
            outputStream.flush();
            i = bis.read(buff);
        }
        bis.close();
        outputStream.close();
    }


    @PostMapping("/getFileAutoCache")
    public String getFileAutoCache(@RequestBody CacheFileParams cacheFileParams) throws ExecutionException, InterruptedException {
        cacheFileParams.setDirName(UriUtils.decode(replaceFailName(cacheFileParams.getDirName()), "UTF-8"));
        cacheFileParams.setGroupName(UriUtils.decode(replaceFailName(cacheFileParams.getGroupName()), "UTF-8"));
        File file = new File(RuoYiConfig.getProfile() + "/" + cacheFileParams.getGroupName() + "/" + cacheFileParams.getDirName() + "/" + cacheFileParams.getFileName());
        if (!file.exists()) {
            log.info("getFileAutoCache - {}/{}/{}", cacheFileParams.getGroupName(), cacheFileParams.getDirName(), cacheFileParams.getFileName());
            saveFile(cacheFileParams.getFileUrl(), cacheFileParams.getGroupName() + "/" + cacheFileParams.getDirName(), cacheFileParams.getFileName(),Boolean.TRUE);
        }
        return StringUtils.format("{}/{}/{}/{}", Constants.RESOURCE_PREFIX, UriUtils.encode(cacheFileParams.getGroupName(), "UTF-8"), UriUtils.encode(cacheFileParams.getDirName(), "UTF-8"), cacheFileParams.getFileName());
    }


    @PostMapping()
    public String cacheFile(@RequestBody CacheFileParams cacheFileParams) throws ExecutionException, InterruptedException {
        log.info("dirName - {} - {}", cacheFileParams.getDirName(), cacheFileParams.getFileName());

        String newName = StringUtils.replaceEach(cacheFileParams.getDirName(), new String[]{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}, new String[]{"", "", "", "", "", "", "", "", ""});

        String groupName = StringUtils.replaceEach(cacheFileParams.getGroupName(), new String[]{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}, new String[]{"", "", "", "", "", "", "", "", ""});


        return saveFile(cacheFileParams.getFileUrl(), groupName + "/" + newName, cacheFileParams.getFileName(),Boolean.TRUE);
    }

    @GetMapping()
    public String fileExists(@RequestParam("dirName") String dirName, @RequestParam("fileName") String fileName, @RequestParam("groupName") String groupName) {
        dirName = StringUtils.replaceEach(dirName, new String[]{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}, new String[]{"", "", "", "", "", "", "", "", ""});
        groupName = StringUtils.replaceEach(groupName, new String[]{"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}, new String[]{"", "", "", "", "", "", "", "", ""});


        File file = new File(RuoYiConfig.getProfile() + "/" + UriUtils.decode(groupName, "UTF-8") + "/" + UriUtils.decode(dirName, "UTF-8") + "/" + fileName);
        String text = "not";
        if (file.exists()) {
            text = "ok";
        }
        return text;
    }

}
